import java.util.Random;
import java.util.Scanner;
import java.util.StringTokenizer;
import java.util.ArrayList;

public class World {

	private GameState game;
	private GUI gui;
	private Player player;
	
	public World(GameState a, GUI b, Player c) {
		game = a;
		gui = b;
		player = c;
		player.addGUI(gui);
		player.getInventory().add(0, new Weapon("", "crude", "bone", "fists"));
		player.setMain_Hand((Weapon) player.getInventory().get(0));
		player.get_Main_Hand().setDisplayName("Unarmed");
		player.get_Main_Hand().setVisible(false);
		player.equipArmour(new Armour("On", "common", "cloth", "shirt", "Monk's robe", "It is a plain robe, commonly worn by monks."));
		player.equipArmour(new Armour("On", "common", "cloth", "leggings"));
		player.equipArmour(new Armour("On", "common", "leather", "shoes", "leather sandles", "They are plain leather sandles, you can feel the breeze through your toes."));
	}
	
	public void GenerateWorld() {
		
		Random random = new Random();
		randomItemGenerator randomItem = new randomItemGenerator();
		
		History AbbeyHistory = new History();
		AbbeyHistory.addGeneralHistory("This place was built in 350 by Bartok, the founder of our order. It is said that he could speak with the animals.");
		History LibraryHistory = new History();
		
		Locale Abbey = new Locale("Abbey");
		Abbey.addHistory(AbbeyHistory);
		
		/**************************************************************************************************
		 * 										GUIDE:
		 * 
		 * 		This guide is to aid those who wish to create their own adventures by breaking
		 * 		down the various class constructors and their parameters, as well as help me
		 * 		keep track. I probably should learn to structure my code better. Oh well...
		 * 
		 * 		Creating locations:
		 * 
		 * 		Constructor parameters: (String name, String description)
		 * 		'name' would be something like "your room", or "a hallway" (always lower-case)
		 * 		'description' immediately follows it: "It is dark and smells funny". Start with a capital.
		 * 
		 * 		Creating Exits for your locations:
		 * 
		 * 		Constructor parameters: (String Orientation, String Name, String Description, Location destination)
		 * 		'Orientation' will be something like "To the north", "Heading south" etc.
		 * 		'Name' is self-explanatory: "an iron door", "your dining room door", "a small wooden hatch"
		 * 		'Description' again self-explanatory: "It is dark and forbidding", "It is adorned with gold"
		 * 		'destination' will be the Location that the player ends up when using this exit.
		 * 
		 * 		Static Object:
		 * 
		 * 		A static object is a decorative object that can be interacted with but never picked up. Examples
		 * 		would include a pillar, tree or some other object you don't want the player stuffing in their
		 * 		backpack.
		 * 
		 *********************************************************************************************************/
		
		
		/*********************************************************************************************************
		 * 				Status Effects:
		 * 
		 * 	(<Duration>, <Name of effect>, <statusmessage>, <expirymessage>, gui, additional messages)
		 * 	
		 * 	If the duration is 0 then it will expire when the player's actionpoints return to a normal level
		 * 
		 * 	Use addPenalty(Penalty, how much) to add a penalty e.g addPenalty("Endurance", -5)
		 * 	If you add a health penalty, it will act like a DoT and do that much damage per tick
		 * 	
		 ********************************************************************************************************/
		
				
		
		/*******************************************************************
		 * 
		 * 					Attacks:
		 * 
		 *  (Base move cost, cooldown (use -10 for attacks with no cooldown), damage modifier, name, (optional) proc chance)
		 *  
		 *  Use addEffect to add a status effect, which has a chance of proccing according to your optional parameter (100% by default)
		 */
		
		
		/****************************************************************************
		 * 					Create The Locations In The Game						*		
		 * 			New Location (display name, target name, description)			*
		 ****************************************************************************/
		
		// Create the player's starting location, their cell
		Location PlayerCell = new Location("your cell", "As you would expect from a monk's cell, it is" +
				" austere and plain, with a cold wooden floor bordered by plain stone walls. If you strain your" +
				" ears you can hear somebody pacing about on the floor below");
		
		PlayerCell.addEntity(new StaticObject("Set into the back wall", "a window", "window", "the light from the setting " +
				"sun is projecting a shadow on the adjacent wall. Gazing through the window, you can see a stunning view of " +
				"mountain range in which the monastery is set"));
		
		PlayerCell.addEntity(new StaticObject("Against one wall", "your bed", "bed", "It is a small, simple cot with rough " +
				"cotton sheets and a thin mattress resting upon wooden slats"));
		
		StaticObject PlayerWardrobe = new StaticObject("By the doorway", "your wardrobe", "wardrobe", "It is a plain, wooden wardrobe used for keeping your spare clothes");
		PlayerWardrobe.addEntities(new Armour("In", "common", "cloth", "shirt"), new Armour("In", "common", "cloth", "leggings"), new Armour("In", "common", "steel", "boots"));
		PlayerWardrobe.setContentsVisible(false);
		
		PlayerCell.addEntity(PlayerWardrobe);
		
		StaticObject PlayerDesk = new StaticObject("Opposite the bed", "your desk", "desk", "Fashioned from dark mahogany, it " +
				"is stained from years of wax and ink spills. A few gouges and scratches betray its old age");
		
		PlayerDesk.addEntity(new StaticObject("Under", "a wooden stool", "stool", "It is a roughly-made wooden stool, clearly " +
				"designed for practicality rather than comfort"));
		
		StaticObject PlayerDeskDrawer = new StaticObject("In", "a drawer", "drawer", "It is a simple wooden drawer, " +
				"matching the desk it belongs to. A metal nub operates as a handle");
		
		Item CellKey = new Item("In", "the key to your cell", "cell key", "It is a simple iron key, worn from " +
				"years of use", 0.1);
		
		PlayerDeskDrawer.addEntity(CellKey);	
		PlayerDeskDrawer.setContentsVisible(false);
		PlayerDesk.addEntity(PlayerDeskDrawer);
		PlayerDesk.addEntity(new Item("On", "a pot of ink", "ink", "It is a simple glass pot of ink, used extensively during your studies", 0.0));
		PlayerDesk.addEntity(new Item("On", "a quill", "quill", "It is a goose feather, scratched meticulously into a point", 0.0));
		PlayerDesk.addEntity(new Item("On", "a book", "book", "It is a poetry book", 0.1, 5));
		PlayerCell.addEntity(PlayerDesk);
		
		// Create Hallway001
		Location Hallway001 = new Location("the hallway outside your cell", "Rough flagstones stretch off in either direction, " +
				"providing cool relief to your feet. Wooden beams run along the length of the vaulted ceiling");
		
		Hallway001.addEntity(new StaticObject("Set into the wall", "a window", "window", "You can see into the main courtyard " +
				"at the entrance to the abbey. The main feature are the formidable gates, however you can just make out the stables " +
				"if you crane your neck"));
		
		Hallway001.addEntity(new StaticObject("Highlighted by the light coming in through the window", "a beam of dust motes", "motes", "You find the way they swirl and shine in the light almost hypnotising"));
		
		Character Torvus = new Character("Waiting outside your door", "Torvus", "Torvus", "Like all of the monks in the monastery, the top of his head is kept bald by rubbing it with a pumice stone. He is clean shaven, his face rough from years of toiling in the fields.", 300, null, gui);
		Torvus.equipArmours(new Armour("On", "common", "cloth", "leggings"), new Armour("On", "common", "leather", "shoes", "a pair of sandles", "They are a common pair of sandles worn by people all over the country"), new Armour("on", "common", "cloth", "shirt", "monk's robe", "It is a common monk's robe as worn by most members of the order"));
		Hallway001.addCharacter(Torvus);
		
		Torvus.addTopic("Abbot", "The abbot is the leader of our order, you can find him in his quarters just by the abbey");
		
		
		// Create Hallway002
		Location Hallway002 = new Location("one of the many hallways in the monastery", "The flagstones continue onward, as" +
				" do the wooden beams running along the ceiling");
		
		Hallway002.addEntity(new StaticObject("Fixed to the wall", "a candelabra", "candelabra", "It consists of a candle " +
				"set into a metal frame, bolted to the wall. Shadows dance all around from the flickering flame"));
		
		Hallway002.addEntity(new StaticObject("Scratched into the wall", "an indecipherable scribble", "scribble", "It looks like some graffiti left behind some time ago by an unruly student, perhaps an in-joke with a friend"));
		
		// Create Hallway003
		Location Hallway003 = new Location("one of the many hallways in the monastery", "The flagstones continue onward, as" +
		" do the wooden beams running along the ceiling");
		
		Hallway003.addEntity(new StaticObject("Fixed to the wall", "a candelabra", "candelabra", "It consists of a candle " +
		"set into a metal frame, bolted to the wall. Shadows dance all around from the flickering flame"));
		
		Hallway003.addEntity(new StaticObject("Along the wall", "some crumbling stonework", "stonework", "It looks as though" +
				" it could do with some restoration work as the many centuries take their toll on the abbey's infrastructure"));
		
		// Create Hallway004
		Location Hallway004 = new Location("one of the many hallways in the monastery", "The flagstones continue onward, as" +
		" do the wooden beams running along the ceiling");
		
		Hallway004.addEntity(new StaticObject("Hanging on the wall", "a large painting", "painting", "It is a painting of " +
				"Bartok, the founder of the abbey over 1000 years ago"));
		
		Hallway004.addEntity(new StaticObject("Against the opposite wall", "a glass cabinet", "cabinet", "It is a large oaken cabinet with a sturdy glass panel on the front to display its contents. The lack of scuff marks around the keyhole suggest it is only rarely opened."));
		Hallway004.addEntity(new StaticObject("In the cabinet", "an array of dusty-looking books", "books", "The writing is faded and it's difficult to make out the writing on their spines, but it looks like they are history books concerning the land"));
		
		
		// Create Hallway005
		Location Hallway005 = new Location("one of the many hallways in the monastery", "The flagstones continue onward, as" +
		" do the wooden beams running along the ceiling");
		
		Item AncientTabard = new Item("In", "an ancient-looking tabard", "tabard", "Judging by the style and emblem on the front, it must date back to the Great Scism nearly 500 years ago", 0);
		AncientTabard.CantBePickedUp("It is safely ensconsed within the cabinet. Besides, it's an ancient artifact and trying to tamper with it is not recommended.");		
		Hallway005.addEntity(new StaticObject("Against the wall", "a glass cabinet", "glass cabinet", "It is a mahogany cabinet with glass doors for display purposes", AncientTabard));
		
		// Create Hallway006
		Location Hallway006 = new Location("one of the many hallways in the monastery", "The flagstones continue onward, as" +
		" do the wooden beams running along the ceiling");
		Item BookQuest001 = new Item("On the floor", "a copy of Bartok's riddles", "book of riddles", "It is a riddle book written by Bartok himself, said to have been composed over the course of his life on his many travels", 0.1);
		Hallway006.addEntity(BookQuest001);
		
		// Create AbbeyGarden
		Location AbbeyGarden = new Location("a beautiful garden, located within the monastery", "It is a place of refuge for those " +
				"seeking solitude and a chance to be alone with their thoughts");
		
		StaticObject AbbeyGardenTree = new StaticObject("In the centre of the garden", "a large sycamour tree", "tree", "You remember sitting under this tree, doing your studies during hot summer days and watching the seeds whirl down around you");
		Consumable Apple001 = new Consumable("At the foot of", "an apple", "apple", "It looks fresh", 0.1, 10);
		AbbeyGardenTree.addEntity(Apple001);
		AbbeyGardenTree.setContentsVisible(false);
		AbbeyGarden.addEntity(AbbeyGardenTree);
		
		// Create AbbeyAtrium001
		
		Location AbbeyAtrium001 = new Location("a large atrium within the monastery", "A high, vaulted ceiling stretches upwards over wood panelled walls. A set of windows near the apex allow beams of sunlight to stream in, illuminating the room.");
		AbbeyAtrium001.addEntity(new StaticObject("In the centre of the atrium", "A large stone pillar", "stone pillar", "It rises all the way up to the apex of the vaulted ceiling"));
		AbbeyAtrium001.addEntity(new StaticObject("On one wall", "a huge oil painting", "painting", "It is gigantic, drawing the eye of all who enter the atrium directly to it. It is an image of the Great Schism, showing Bartok leading the righteous from the corruption of the old order in 327"));
		AbbeyAtrium001.addEntity(new StaticObject("Hanging overhead", "a huge chandelier", "chandelier", "It must weigh a tonne, and you count 48 candles arranged in a double-decker layout. Every evening, one unlucky acolyte is assigned to light every one, and change the candles every two days. Not a job you'd want."));
		
		// Create AbbeyLibrary001
		
		Location AbbeyLibrary001 = new Location("the entrance to the abbey library", "The abbey library is like a labyrinth, with many a student disappearing for hours trying to find their way back out. The light levels are fairly low due to the lack of access to sunlight, and the dusty, musty smell of thousands of old tomes brings a warm, comforting feeling");
		AbbeyLibrary001.addEntity(new StaticObject("Lining every wall", "a set of candles", "candles", "They bathe the library in a warm, pleasing glow, and due to the silence that pervades the library, it's not unusual to find students fast asleep among their books"));
		StaticObject AbbeyShelving001 = new StaticObject("Stretching as far as the eye can see", "an impressive array of shelving, loaded with books", "shelving books", "Sometimes it's hard to fathom just how many books there are here. The abbey is reknowned for holding the largest collection of books for a thousand miles");
		
		AbbeyShelving001.setContentsVisible(false);
		AbbeyLibrary001.addEntity(AbbeyShelving001);
		AbbeyLibrary001.Link(AbbeyAtrium001, "south", "a huge archway", "Intricate and skilled stonework arches over your head, forming the entrance of the library", false);
		Character Student001 = new Character("Huddled in the corner", "an agitated-looking student", "The agitated student", "He is buried in amongst his books, and appears to be quite agitated. Perhaps he is behind on his studies and fears the wrath of his tutor.", 0, null, gui);
		Student001.equipArmours(new Armour("On", "common", "cloth", "leggings"), new Armour("On", "common", "leather", "shoes", "a pair of sandles", "They are a common pair of sandles worn by people all over the country"), new Armour("on", "common", "cloth", "shirt", "monk's robe", "It is a common monk's robe as worn by most members of the order"));
		AbbeyLibrary001.addCharacter(Student001);
		Quest Quest002 = new Quest("Riddle me this", "Excuse me, I'm really behind with my studies and I can't find my copy of Bartok's riddles, I must have dropped it on my way here. If you could find it for me I'd be so grateful!", "Oh perfect! Thank you so much. Here, take this wine flask, I better not touch it or I might fall asleep!", player, "killed", Torvus);
		Quest002.addRewards(5, new Consumable("On", "a flask of wine", "flask of wine", "You're not sure what's in it exactly, but you're glad for a bit of refreshment", 0.5, 15));
		Student001.addQuest(Quest002);
		
		// Create AbbeyLibrary002
		
		Location AbbeyLibrary002 = new Location("the west wing of the abbey library", "The bookshelves continue onwards, arranged in a two-tier format with sliding ladders to allow patrons to access the higher shelves.");
		AbbeyLibrary002.addEntity(new StaticObject("Hanging in the air", "a haze of dust motes", "dust motes", "They dance and twinkle in the air, and carry a musty smell from the ancient books that surroud you"));
		AbbeyLibrary002.addEntity(new StaticObject("On either side", "a series of bookshelves", "bookshelves", "Sweeping your gaze across the shelves you can make out books on history, philosophy, the arts and even combat"));
		Character Student002 = new Character("Browsing the shelves", "a student", "the student", "He is one of the acolytes in the monastery, hoping to one day become a fully fledged member of the order. Many years of study and discipline await him.", 0, null, gui);
		AbbeyLibrary002.addCharacter(Student002);
		
		// Create AbbeyCellar001
		
		Location AbbeyCellar001 = new Location("one of the many cellars in the abbey", "It is dark and the smell of decay fills the air, you can barely make out your surroundings");
		Weapon Claws = new Weapon("On", "common", "bone", "fists", "claws");
		Monster GiantRat = new Monster("Hunkered in the corner", "a giant rat", "The giant rat", "It is an oversized rat", gui, Claws);
		AbbeyCellar001.addCharacter(GiantRat);
		
		AbbeyCellar001.Link(AbbeyLibrary002, "east", "a cellar door", "it is a cellar door", false);
		
		
		
		
		/*****************************************************************************
		 * 		Create and link up the exits, and create any necessary keys			 *
		 * 		New Key (Orientation, display name, target name, description)		 *
		 * 		Lock door with StartsLocked(true), assign a key with NeedsKey(Key)	 *
		 *****************************************************************************/
		
		PlayerCell.Link(Hallway001, "north", "your cell door", "It is a heavyset wooden door", true, CellKey);
		
		Hallway001.Link(Hallway002, "east", "a passageway", "The hallway continues onwards", false);
		
		Hallway001.Link(Hallway003, "west", "another passageway", "The hallway stretches on", false);
		Hallway003.Link(AbbeyAtrium001, "west", "a sturdy set of double doors", "Two heavy iron rings hang from each door, acting as handles. The oak is trimmed with metal, and studs are set into the door", false);
		
		Hallway002.Link(AbbeyGarden, "east", "a large oaken door", "It is a sturdy oaken door, the solid wood punctuated by scuff marks", false);
		Hallway002.addEntity(new StaticObject("to the north and south", "a pair of room doors", "room doors", "Like the door to your room, they have a window set at eye level. Looking in, you can see into the other monks' rooms"));
		
		AbbeyGarden.Link(Hallway006, "north", "a heavy set of double doors", "It is a pair of oaken doors, adorned with metal studs and heavy iron handles", false);
		
		AbbeyGarden.Link(Hallway005, "south", "a doorway", "Like the other doors leading out of the abbey garden, they are adorned with metal studs and heavy iron handles", false);
		AbbeyLibrary001.Link(AbbeyLibrary002, "west", "a small staircase", "It's a small stone staircase, leading deeper into the library", false);
		/******************************************************************************
		 *  Create all of the objects in the game and assign them to their locations  *
		 *       New Object (Orientation, display name, target name, Description)     *
		 *       Add an object to another object's inventory with addEntity(object)   *
		 ******************************************************************************/

		Quest Quest001 = new Quest("The hungry monk", "Hi there! I missed breakfast today and I was wondering if you could scrounge up an apple for me? I'd be eternally grateful!", "Oh thank you so much, that looks delicious!", player, "has", Apple001);
		Quest001.addRewards(5);
		
		Torvus.addQuest(Quest001);
	
		
		Abbey.addLocations(PlayerCell, Hallway001, Hallway002, Hallway003, Hallway004, Hallway005, Hallway006, AbbeyGarden, AbbeyAtrium001, AbbeyLibrary001);
		
		game.addLocation(PlayerCell);
		player.setLocation(PlayerCell);
		
		game.setPlayer(player);
		game.setGUI(gui);
		

		
	}
	
}
